<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="./js/ctx.js"></script>
</head>
<style>
    #toolbar {
        background: rgba(42, 42, 42, 0.8);
        padding: 4px;
        border-radius: 4px;
    }
    #toolbar input {
        vertical-align: middle;
        padding-top: 2px;
        padding-bottom: 2px;
    }
    #toolbar .header {
        font-weight: bold;
    }
</style>
<body>
<div id="cesiumContainer">
</div>
<div id="toolbar">
    <select data-bind="options: exampleTypes, value: currentExampleType"></select>
    <input type="checkbox" value="false" data-bind="checked: debugBoundingVolumesEnabled, valueUpdate: 'input'"> Show bounding volume
    <input type="checkbox" value="true" data-bind="checked: edgeStylingEnabled, valueUpdate: 'input'"> Enable edge styling
</div>
<script>
    var initCesium = new InitCesium();
    var viewer = initCesium.initViewer('cesiumContainer',{
        infoBox: false,
        selectionIndicator: false
    });
    // Add a clipping plane, a plane geometry to show the representation of the
    // plane, and control the magnitude of the plane distance with the mouse.

    var scene = viewer.scene;

    var clipObjects = ['BIM', 'Point Cloud', 'Instanced', 'Model'];
    var viewModel = {
        debugBoundingVolumesEnabled : false,
        edgeStylingEnabled : true,
        exampleTypes : clipObjects,
        currentExampleType : clipObjects[0]
    };

    var targetY = 0.0;
    var planeEntities = [];
    var selectedPlane;
    var clippingPlanes;

    // Select plane when mouse down
    var downHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    downHandler.setInputAction(function(movement) {
        var pickedObject = scene.pick(movement.position);
        if (Cesium.defined(pickedObject) &&
                Cesium.defined(pickedObject.id) &&
                Cesium.defined(pickedObject.id.plane)) {
            selectedPlane = pickedObject.id.plane;
            selectedPlane.material = Cesium.Color.WHITE.withAlpha(0.05);
            selectedPlane.outlineColor = Cesium.Color.WHITE;
            scene.screenSpaceCameraController.enableInputs = false;
        }
    }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

    // Release plane on mouse up
    var upHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    upHandler.setInputAction(function() {
        if (Cesium.defined(selectedPlane)) {
            selectedPlane.material = Cesium.Color.WHITE.withAlpha(0.1);
            selectedPlane.outlineColor = Cesium.Color.WHITE;
            selectedPlane = undefined;
        }

        scene.screenSpaceCameraController.enableInputs = true;
    }, Cesium.ScreenSpaceEventType.LEFT_UP);

    // Update plane on mouse move
    var moveHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    moveHandler.setInputAction(function(movement) {
        if (Cesium.defined(selectedPlane)) {
            var deltaY = movement.startPosition.y - movement.endPosition.y;
            targetY += deltaY;
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    function createPlaneUpdateFunction(plane) {
        return function () {
            plane.distance = targetY;
            return plane;
        };
    }

    var tileset;
    function loadTileset(url) {
        clippingPlanes = new Cesium.ClippingPlaneCollection({
            planes : [
                new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, -1.0), 0.0)
            ],
            edgeWidth : viewModel.edgeStylingEnabled ? 1.0 : 0.0
        });

        tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
            url : url,
            clippingPlanes : clippingPlanes
        }));

        tileset.debugShowBoundingVolume = viewModel.debugBoundingVolumesEnabled;
        return tileset.readyPromise.then(function() {
            var boundingSphere = tileset.boundingSphere;
            var radius = boundingSphere.radius;

            viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0));

            for (var i = 0; i < clippingPlanes.length; ++i) {
                var plane = clippingPlanes.get(i);
                var planeEntity = viewer.entities.add({
                    position : boundingSphere.center,
                    plane : {
                        dimensions : new Cesium.Cartesian2(radius * 2.5, radius * 2.5),
                        material : Cesium.Color.WHITE.withAlpha(0.1),
                        plane : new Cesium.CallbackProperty(createPlaneUpdateFunction(plane), false),
                        outline : true,
                        outlineColor : Cesium.Color.WHITE
                    }
                });

                planeEntities.push(planeEntity);
            }
            return tileset;
        }).otherwise(function(error) {
            console.log(error);
        });
    }

    function loadModel(url) {
        clippingPlanes = new Cesium.ClippingPlaneCollection({
            planes : [
                new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, -1.0), 0.0)
            ],
            edgeWidth : viewModel.edgeStylingEnabled ? 1.0 : 0.0
        });

        var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 100.0);
        var heading = Cesium.Math.toRadians(135.0);
        var pitch = 0.0;
        var roll = 0.0;
        var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
        var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
        var entity = viewer.entities.add({
            name : url,
            position : position,
            orientation : orientation,
            model : {
                uri : url,
                scale : 8,
                minimumPixelSize : 100.0,
                clippingPlanes : clippingPlanes
            }
        });

        viewer.trackedEntity = entity;

        for (var i = 0; i < clippingPlanes.length; ++i) {
            var plane = clippingPlanes.get(i);
            var planeEntity = viewer.entities.add({
                position : position,
                plane : {
                    dimensions : new Cesium.Cartesian2(300.0, 300.0),
                    material : Cesium.Color.WHITE.withAlpha(0.1),
                    plane : new Cesium.CallbackProperty(createPlaneUpdateFunction(plane), false),
                    outline : true,
                    outlineColor : Cesium.Color.WHITE
                }
            });

            planeEntities.push(planeEntity);
        }
    }

    // Power Plant design model provided by Bentley Systems
    var bimUrl = Cesium.IonResource.fromAssetId(8564);
    var pointCloudUrl = Cesium.IonResource.fromAssetId(5714);
    var instancedUrl = '../data/Cesium3DTiles/Instanced/InstancedOrientation/tileset.json';
    var modelUrl = '../data/models/CesiumAir/Cesium_Air.glb';

    loadTileset(bimUrl);

    // Track and create the bindings for the view model
    var toolbar = document.getElementById('toolbar');
    Cesium.knockout.track(viewModel);
    Cesium.knockout.applyBindings(viewModel, toolbar);

    Cesium.knockout.getObservable(viewModel, 'currentExampleType').subscribe(function(newValue) {
        reset();

        if (newValue === clipObjects[0]) {
            loadTileset(bimUrl);
        } else if (newValue === clipObjects[1]) {
            loadTileset(pointCloudUrl);
        } else if (newValue === clipObjects[2]) {
            loadTileset(instancedUrl);
        } else {
            loadModel(modelUrl);
        }
    });

    Cesium.knockout.getObservable(viewModel, 'debugBoundingVolumesEnabled').subscribe(function(value) {
        if (Cesium.defined(tileset)) {
            tileset.debugShowBoundingVolume = value;
        }
    });

    Cesium.knockout.getObservable(viewModel, 'edgeStylingEnabled').subscribe(function(value) {
        var edgeWidth = value ? 1.0 : 0.0;

        clippingPlanes.edgeWidth = edgeWidth;
    });

    function reset() {
        viewer.entities.removeAll();
        viewer.scene.primitives.remove(tileset);
        planeEntities = [];
        targetY = 0.0;
        tileset = undefined;
    }


</script>
</body>

</html>